package system.task.quartz;

import framework.runtime.SystemContext;
import framework.storage.FileStorage;
import lombok.Getter;
import org.apache.http.HttpEntity;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.util.StringUtils;
import system.task.ExecutorContext;
import system.task.Task;
import system.task.TaskExecutor;
import system.task.TaskLogger;
import system.task.errors.TaskException;

import java.nio.charset.Charset;

/**
 * HTTP job
 */
public abstract class HttpJob implements TaskExecutor {

    @Getter
    private final String url;

    public HttpJob(String url) {
        this.url = url;
    }

    protected abstract HttpUriRequest createRequest(URIBuilder builder, HttpJobParam jobParam, HttpClient httpClient);

    @Override
    public void run(ExecutorContext context) throws Exception {
        TaskLogger logger = context.getLogger();
        Task task = context.getTask();

        //
        URIBuilder builder = new URIBuilder(this.url);

        //
        HttpJobParam jobParam = HttpJobParam.parse(context);

        //
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(jobParam.connectTimeout)
                .setSocketTimeout(jobParam.socketTimeout)
                .build();

        // 创建 HttpClient 对象
        try (CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultHeaders(jobParam.headers)
                .setDefaultCookieStore(jobParam.cookieStore)
                .setDefaultRequestConfig(requestConfig)
                .build()) {

            // 创建 GET 请求
            HttpUriRequest request = this.createRequest(builder, jobParam, httpClient);

            // 发送请求并获取响应
            try (CloseableHttpResponse response = httpClient.execute(request)) {

                // 获取响应状态码
                StatusLine statusLine = response.getStatusLine();
                int statusCode = statusLine.getStatusCode();

                // 获取响应实体
                HttpEntity entity = response.getEntity();
                if (entity == null)
                    throw new RuntimeException("No response result");

                //
                try {

                    if (statusCode != 200) {
                        logger.error("Task " + task.getGroupName() + "." + task.getName() + " fail response code: " + String.valueOf(statusLine));
                        logger.error(EntityUtils.toString(entity));
                        throw new TaskException("Task " + task.getGroupName() + "." + task.getName() + " fail response code: " + String.valueOf(statusLine));
                    }

                    // 打印响应结果
                    if (jobParam.output == null) {
                        logger.write(EntityUtils.toString(entity, Charset.forName(jobParam.charset)));
                    } else if (StringUtils.hasText(jobParam.output)) {
                        String path = jobParam.output;
                        if (!path.endsWith("/"))
                            path = path + "/";
                        path = path + context.getRunId();
                        FileStorage storage = SystemContext.getBean(FileStorage.class);
                        storage.save(entity.getContent(), path);
                    } else {
                        logger.writeln("COMPLETED");
                    }

                } finally {
                    EntityUtils.consume(entity);
                }
            }
        }
    }
}
